package com.example.demo.utils;

import cn.hutool.json.JSONObject;
import com.example.demo.config.WechatConfig;
import com.example.demo.bo.Code2SeassionBO;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;

/**
 * <h3>wechat-token</h3>
 * <p>微信端工具类</p>
 *
 * @author : zhengyue
 * @date : 2021-02-20 10:21
 **/
@Component
@Slf4j
public class WechatUtils {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * @Description: 获取access_token，没过半个小时刷新一次
     * @Author: zhengyue
     * @Date: 2021/2/20 10:31
     * @Param: 
     * @Return: 
     */
    @Scheduled(cron = "0 0/30 * * * ? ")
    // 程序启动执行一次，保证acess_token一开始就存在
    @PostConstruct
    public void getAccessToken() {
        log.info("access_token开始刷新");
        String res = restTemplate.getForObject(WechatConfig.AUTH_ACCESS_TOKEN_URL, String.class);
        // 正常返回
        // {"access_token":"ACCESS_TOKEN","expires_in":7200}
        // 错误时返回
        // {"errcode":40013,"errmsg":"invalid appid"}
        if(!res.contains(Constant.ACCESS_TOKEN)) {
            return;
        }
        String token = new JSONObject(res).get(Constant.ACCESS_TOKEN, String.class);
        // 存入redis 有效时间7200s
        redisUtils.set(Constant.ACCESS_TOKEN, token);
        redisUtils.expire(Constant.ACCESS_TOKEN, Constant.ACCESS_TOKEN_EXPIRE);
    }

    /***
     * @Description: 获取session_key
     * @Author: zhengyue
     * @Date: 2021/5/18 15:49
     * @Param: []
     * @Return: java.lang.String
     */
    public Code2SeassionBO getSessionKey(String jscode) {
        String res = restTemplate.getForObject(WechatConfig.CODE2SESSION_URL
                + jscode, String.class);
        // 参数拷贝
        JSONObject code2Session = new JSONObject(res);
        Code2SeassionBO bo = new Code2SeassionBO();
        bo.setSession_key(code2Session.getStr("session_key"));
        bo.setOpenid(code2Session.getStr("openid"));
        return bo;
    }

    /**
     * 微信解密运动步数
     *
     * @param sessionKey
     * @param encryptedData
     * @param iv
     * @return
     */
    public String decryptWeChatRun(String sessionKey, String encryptedData, String iv) {
        String result = null;
        byte[] encrypData = Base64.decodeBase64(encryptedData);
        byte[] ivData = Base64.decodeBase64(iv);
        byte[] sessionKeyB = Base64.decodeBase64(sessionKey);
        try {
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(sessionKeyB, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            byte[] doFinal = cipher.doFinal(encrypData);
            result = new String(doFinal);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

}
